package com.glela.order.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.glela.cache.redis.RedisKeys;
import com.glela.cache.redis.RedisUtil;
import com.glela.common.constant.BaseRestrictionsEnum;
import com.glela.common.constant.PayTypeEnum;
import com.glela.common.constant.StatusEnum;
import com.glela.common.exception.PlatformException;
import com.glela.goods.mapper.GoodsExtendedAttributeMapper;
import com.glela.goods.mapper.GoodsMapper;
import com.glela.goods.model.Goods;
import com.glela.goods.model.GoodsExtends;
import com.glela.order.dao.OrderDao;
import com.glela.order.mapper.OrderDetailMapper;
import com.glela.order.mapper.OrderInfoMapper;
import com.glela.order.mapper.OrderObjectMapper;
import com.glela.order.model.OrderDetail;
import com.glela.order.model.OrderInfo;
import com.glela.order.model.OrderObject;
import com.glela.order.model.PayTypeConfig;
import com.glela.order.model.PayTypeList;
import com.glela.order.model.response.OrderInfoVo;
import com.glela.order.model.response.OrderObjectVo;
import com.glela.order.service.OrderObjectService;
import com.glela.order.service.PayTypeConfigService;
import com.glela.platform.mapper.UserMapper;
import com.glela.platform.model.BaseRestrictions;
import com.glela.platform.model.request.ReqHeaderVo;
import com.glela.platform.model.request.RequestPageBaseModel;
import com.glela.platform.model.response.ResponseUser;
import com.glela.platform.service.BaseRestrictionsService;

@Service("orderObjectService")
public class OrderObjectServiceImpl implements OrderObjectService {
	private static Logger logger = LoggerFactory.getLogger(OrderObjectServiceImpl.class);

	@Autowired
	private OrderInfoMapper			orderInfoMapper;
	@Autowired
	private OrderDetailMapper		orderDetailMapper;
	@Autowired
	private OrderObjectMapper		orderObjectMapper;
	@Autowired
	private GoodsMapper				goodsMapper;
	@Autowired
	protected OrderDao				orderDao;
	@Autowired
	private PayTypeConfigService	payTypeConfigService;
	@Autowired
	private UserMapper				userMapper;
	@Autowired
	private RedisUtil				redisUtil;
	@Autowired
	private BaseRestrictionsService	baseRestrictionsService;
	@Autowired
	private GoodsExtendedAttributeMapper	goodsExtendedAttributeMapper;

	@Override
	public List<OrderObjectVo> listOrderObjectDaiZhiFuByUserId(long userId, int page, int pageSize) {
		List<OrderObjectVo> orderObjectVoList = new ArrayList<OrderObjectVo>();
		List<OrderObject> orderObjectList = orderObjectMapper.selectOrderObjectDaizhifuByUserId(userId, page, pageSize);
		for (OrderObject orderObject : orderObjectList) {
			List<OrderInfo> orderInfoList = orderInfoMapper.selectOrderInfoByOrderObjectIdC(orderObject.getId());
			List<OrderInfoVo> listOrderInfoVo = new ArrayList<OrderInfoVo>();
			for (OrderInfo OrderInfo : orderInfoList) {
				List<OrderDetail> listOrderDetail = orderDetailMapper.selectOrderDetailByOrderInfoIdC(OrderInfo.getId());
				OrderInfoVo orderInfoVo = new OrderInfoVo();
				orderInfoVo.setListOrderDetail(listOrderDetail);
				orderInfoVo.setOrderInfoVo(OrderInfo);
				listOrderInfoVo.add(orderInfoVo);
			}
			OrderObjectVo orderObjectVo = new OrderObjectVo();
			orderObjectVo.setOrderInfoVoList(listOrderInfoVo);
			orderObjectVo.setOrderObjectVo(orderObject);
			orderObjectVoList.add(orderObjectVo);
		}
		return orderObjectVoList;
	}

	@Override
	public OrderObjectVo getOrderObjectEntityByOrderSn(String clientType, String orderSn, long userId) {
		int goodsType = 0;
		OrderObjectVo orderObjectVo = new OrderObjectVo();
		OrderObject orderObject = orderObjectMapper.selectOrderObjectByOrderSn(orderSn);
		orderObjectVo.setOrderObjectVo(orderObject);
		List<OrderInfo> orderInfoList = orderInfoMapper.selectOrderInfoByOrderObjectIdC(orderObject.getId());
		List<OrderInfoVo> listOrderInfoVo = new ArrayList<OrderInfoVo>();
		for (OrderInfo OrderInfo : orderInfoList) {
			List<OrderDetail> listOrderDetail = orderDetailMapper.selectOrderDetailByOrderInfoIdC(OrderInfo.getId());
			for (OrderDetail orderDetail : listOrderDetail) {
				goodsType = orderDetail.getGoodsType();
				if (orderDetail.getStatus() == 1 || orderDetail.getStatus() == 5 || orderDetail.getStatus() == 6 || orderDetail.getStatus() == 7) {
					orderDetail.setIsAfterSale(0);
				}
				if (orderDetail.getStatus() == 2 || orderDetail.getStatus() == 3 || orderDetail.getStatus() == 4) {
					orderDetail.setIsAfterSale(1);
				}
				Goods goods = goodsMapper.selectGoodsById(orderDetail.getGoodId());
				// 返还现金币金额（总结算成本价*消费积分/100*商品数量）
				float aaaaaa = orderDetail.getTotalPrice() * (goods.getScoreRate() / 100f);
				orderDetail.setBacktrackCash(aaaaaa);
			}
			OrderInfoVo orderInfoVo = new OrderInfoVo();
			orderInfoVo.setListOrderDetail(listOrderDetail);
			if (userId > 0) {
				String linkMan = OrderInfo.getLinkMan().substring(0, 1) + "**";
				String address = "*****";
				String mobile = OrderInfo.getMobile().substring(0, 3) + "******" + OrderInfo.getMobile().substring(9, 11);
				OrderInfo.setLinkMan(linkMan);
				OrderInfo.setAddress(address);
				OrderInfo.setMobile(mobile);
			} else {
				OrderInfo.setLinkMan(OrderInfo.getLinkMan());
				OrderInfo.setAddress(OrderInfo.getAddress());
				OrderInfo.setMobile(OrderInfo.getMobile());
			}
			orderInfoVo.setOrderInfoVo(OrderInfo);
			listOrderInfoVo.add(orderInfoVo);
			orderObjectVo.setOrderInfoVoList(listOrderInfoVo);
			orderObjectVo.setOrderObjectVo(orderObject);
			List<PayTypeConfig> payTypeConfigList = selectPayTypeConfigByStatus(StatusEnum.S1.getCode());
			List<PayTypeConfig> listPayTypeConfig = new ArrayList<PayTypeConfig>();
			listPayTypeConfig.addAll(payTypeConfigList);
			for (PayTypeConfig payTypeConfig : payTypeConfigList) {
				if (payTypeConfig.getPayType() > 10) {
					if (goodsType == 0) {
						listPayTypeConfig.remove(payTypeConfig);
					}
				}
			}

			orderObjectVo.setPayTypeConfigList(listPayTypeConfig);
		}
		return orderObjectVo;
	}

	@Override
	public OrderObjectVo getOrderObjectEntityByOrderSnNew(RequestPageBaseModel reqModel) {
		//		int goodsType = 0;
		//判断海外购商品
		Long overSeaGoods=null;
		OrderObjectVo orderObjectVo = new OrderObjectVo();
		String orderSn = reqModel.getOrderSn();
		OrderObject orderObject = orderObjectMapper.selectOrderObjectByOrderSn(orderSn);
		orderObjectVo.setOrderObjectVo(orderObject);
		List<OrderInfo> orderInfoList = orderInfoMapper.selectOrderInfoByOrderObjectIdC(orderObject.getId());
		List<OrderInfoVo> listOrderInfoVo = new ArrayList<OrderInfoVo>();
		for (OrderInfo OrderInfo : orderInfoList) {
			List<OrderDetail> products = new ArrayList<OrderDetail>();//非赠品行
			List<OrderDetail> giftsProducts = new ArrayList<OrderDetail>();//赠品行
			//所有行
			List<OrderDetail> listOrderDetail = orderDetailMapper.selectOrderDetailByOrderInfoIdC(OrderInfo.getId());
			for (OrderDetail orderDetail : listOrderDetail) {
				//				goodsType = orderDetail.getGoodsType();
				if (orderDetail.getIsGift() == 0) {//商品行
					if (orderDetail.getStatus() == 1 || orderDetail.getStatus() == 5 || orderDetail.getStatus() == 6 || orderDetail.getStatus() == 7) {
						orderDetail.setIsAfterSale(0);
					}
					if (orderDetail.getStatus() == 2 || orderDetail.getStatus() == 3 || orderDetail.getStatus() == 4) {
						orderDetail.setIsAfterSale(1);
					}
					Goods goods = goodsMapper.selectGoodsByIdTwo(orderDetail.getGoodId());
					// 返还现金币金额（总结算成本价*消费积分/100*商品数量）
					float aaaaaa = orderDetail.getTotalPrice() * (goods.getScoreRate() / 100f);
					orderDetail.setBacktrackCash(aaaaaa);
					products.add(orderDetail);
				} else {
					orderDetail.setIsAfterSale(0);
					//					Goods goods = goodsMapper.selectGoodsById(orderDetail.getGoodId());
					//					// 返还现金币金额（总结算成本价*消费积分/100*商品数量）
					//					float aaaaaa = orderDetail.getTotalPrice() * (float) (goods.getScoreRate() / (float) 100);
					//					orderDetail.setBacktrackCash(aaaaaa);
					giftsProducts.add(orderDetail);
				}
			//海外购商品
				if(overSeaGoods==null) {
					GoodsExtends goodsExtends=goodsExtendedAttributeMapper.selectExtendsAttrByGoodsID(orderDetail.getGoodId());
					if(goodsExtends!=null&&goodsExtends.getOverseasGoods()==1) {//有海外购产品
						overSeaGoods=orderDetail.getGoodId();
					}
				}
			}
			OrderInfoVo orderInfoVo = new OrderInfoVo();
			//			orderInfoVo.setListOrderDetail(listOrderDetail);
			orderInfoVo.setListOrderDetail(products);//商品行
			orderInfoVo.setGiftsProducts(giftsProducts);//赠品行
			/*if (reqModel.getUserId() > 0) {
				String linkMan = OrderInfo.getLinkMan().substring(0, 1) + "**";
				String address = "*****";
				String mobile = OrderInfo.getMobile().substring(0, 3) + "******" + OrderInfo.getMobile().substring(9, 11);
				OrderInfo.setLinkMan(linkMan);
				OrderInfo.setAddress(address);
				OrderInfo.setMobile(mobile);
			} else {
				OrderInfo.setLinkMan(OrderInfo.getLinkMan());
				OrderInfo.setAddress(OrderInfo.getAddress());
				OrderInfo.setMobile(OrderInfo.getMobile());
			}*/
			//如果订单是自己的不隐藏
			if (reqModel.getUserId().intValue() != OrderInfo.getUserId().intValue()) {
				String linkMan = OrderInfo.getLinkMan().substring(0, 1) + "**";
				String address = "*****";
				String mobile = OrderInfo.getMobile().substring(0, 3) + "******" + OrderInfo.getMobile().substring(9, 11);
				OrderInfo.setLinkMan(linkMan);
				OrderInfo.setAddress(address);
				OrderInfo.setMobile(mobile);

				//				String linkMan1 = orderObject.getLinkMan().substring(0, 1) + "**";
				//				String address1 = "*****";
				//				String mobile1 = orderObject.getMobile().substring(0, 3) + "******" + orderObject.getMobile().substring(9, 11);
				orderObject.setLinkMan(linkMan);
				orderObject.setAddress(address);
				orderObject.setMobile(mobile);
			} else {
				OrderInfo.setLinkMan(OrderInfo.getLinkMan());
				OrderInfo.setAddress(OrderInfo.getAddress());
				OrderInfo.setMobile(OrderInfo.getMobile());
			}
			orderInfoVo.setOrderInfoVo(OrderInfo);
			listOrderInfoVo.add(orderInfoVo);
			orderObjectVo.setOrderInfoVoList(listOrderInfoVo);
			orderObjectVo.setOrderObjectVo(orderObject);
		}
		//实付金额不为0才显示支付类型列表
		if (orderObjectVo.getTotalFee() > 0) {
			ResponseUser payUser = userMapper.selectUserRoleById(orderObject.getUserId());
			boolean isOpenStoreOrder = false;
			if (orderObject.getOpenStore() != null && orderObject.getOpenStore() == 1) {
				isOpenStoreOrder = true;
			}
			orderObjectVo.setPayTypeConfigList(this.queryOrderPayType(isOpenStoreOrder, reqModel.getReqHeader(), payUser));
		} else {
			orderObjectVo.setPayTypeConfigList(new ArrayList<PayTypeConfig>());
		}
		if(overSeaGoods!=null) {//是海外购订单
			orderObjectVo.setIsOverseasOrder(1);
		}
		return orderObjectVo;
	}

	@Override
	public List<PayTypeConfig> selectPayTypeConfigByStatus(Integer status) {
		return orderDao.selectPayTypeConfigByStatus(status);
	}

	@Override
	public OrderObjectVo getOrderObjectEntityByOrderSnTwo(String orderSn) {
		OrderObjectVo orderObjectVo = new OrderObjectVo();
		OrderObject orderObject = orderObjectMapper.selectOrderObjectByOrderSnTwo(orderSn);
		orderObjectVo.setOrderObjectVo(orderObject);
		return orderObjectVo;
	}

	@Override
	public List<String> selectOrderObjectHandleStatus() {
		return orderObjectMapper.selectOrderObjectHandleStatus();
	}

	private static Map<String, Long> appVersionMap = new HashMap<>();

	private long _getVersionNum(String appVersion) {
		long versionsNum = -1;
		try {
			if (StringUtils.isBlank(appVersion)) {
				return versionsNum;
			}
			if (appVersionMap.containsKey(appVersion)) {
				versionsNum = MapUtils.getLongValue(appVersionMap, appVersion, -1);
			} else {
				String[] split = StringUtils.split(appVersion, ".");
				versionsNum = 0;

				for (int i = 0; i < split.length; i++) {
					long long1 = NumberUtils.toLong(split[i], 1);
					for (int j = 0; j < split.length - i; j++) {
						long1 *= 1000;
					}
					versionsNum += long1;
				}
				appVersionMap.put(appVersion, versionsNum);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return versionsNum;
	}

	/** 获取支付配置信息 */
	private Map<String, String> getPayCfgInfo(String channle, String version) {
		String key = RedisKeys.ORDER_CFG_PAY + channle + ":" + version;
		if (!redisUtil.exists(key)) {//不存在，缓存渠道下此版本配置
			initPayTypeList(channle, version);
		}
		return redisUtil.hgetAll(key);
	}

	/** 初始化支付类型版本配置 */
	private void initPayTypeList(String channle, String version) {
		if (StringUtils.isAnyBlank(channle, version)) {
			logger.error("获取支付方式时，渠道或版本号为空[{}-{}]", channle, version);
			return;
		}
		PayTypeList queryPayTypeList = new PayTypeList();
		queryPayTypeList.setChannle(channle);
		queryPayTypeList.setVersion(version);
		List<PayTypeList> selectPayTypeList = orderDao.selectPayTypeList(queryPayTypeList);
		if (CollectionUtils.isNotEmpty(selectPayTypeList)) {
			String key = RedisKeys.ORDER_CFG_PAY + channle + ":" + version;
			for (PayTypeList payTypeList : selectPayTypeList) {
				redisUtil.hmset(key, payTypeList.getPayType(), payTypeList.getRoleId());
			}
			//设置默认版本信息
			String defaultVersion = redisUtil.hget(RedisKeys.ORDER_CFG_PAY_DEFAULT, channle);

			if (StringUtils.isBlank(defaultVersion)) {
				defaultVersion = "5.4.6";
				BaseRestrictions baseRestrictionsForCache = baseRestrictionsService.getBaseRestrictionsForCache(BaseRestrictionsEnum.PAY_DEFAULT_VERSION);
				if (baseRestrictionsForCache != null && StringUtils.isNotBlank(baseRestrictionsForCache.getName())) {
					defaultVersion = baseRestrictionsForCache.getName();
				}
				key = RedisKeys.ORDER_CFG_PAY + channle + ":" + defaultVersion;
				if (!redisUtil.exists(key)) {
					initPayTypeList(channle, defaultVersion);
				}
				//				redisUtil.hmset(RedisKeys.ORDER_CFG_PAY_DEFAULT, channle, defaultVersion);
				//				initPayTypeList(channle, defaultVersion);
			}
			if (_getVersionNum(version) >= _getVersionNum(defaultVersion)) {
				redisUtil.hmset(RedisKeys.ORDER_CFG_PAY_DEFAULT, channle, version);
			}
		} else {
			String key = RedisKeys.ORDER_CFG_PAY + channle + ":" + version;
			//没有配置信息，取默认配置
			String defaultVersion = redisUtil.hget(RedisKeys.ORDER_CFG_PAY_DEFAULT, channle);
			if (StringUtils.isBlank(defaultVersion)) {//没有默认配置，初始化默认配置
				defaultVersion = "5.4.6";
				BaseRestrictions baseRestrictionsForCache = baseRestrictionsService.getBaseRestrictionsForCache(BaseRestrictionsEnum.PAY_DEFAULT_VERSION);
				if (baseRestrictionsForCache != null && StringUtils.isNotBlank(baseRestrictionsForCache.getName())) {
					defaultVersion = baseRestrictionsForCache.getName();
				}
				key = RedisKeys.ORDER_CFG_PAY + channle + ":" + defaultVersion;
				if (!redisUtil.exists(key)) {
					logger.error("支付方式默认配置为空，请及时配置：{}", key);
					initPayTypeList(channle, defaultVersion);
				}
			} //有默认配置，设置当前配置为默认配置
			key = RedisKeys.ORDER_CFG_PAY + channle + ":" + defaultVersion;
			Map<String, String> hgetAll = redisUtil.hgetAll(key);
			if (MapUtils.isNotEmpty(hgetAll)) {
				redisUtil.hmset(RedisKeys.ORDER_CFG_PAY + channle + ":" + version, hgetAll);
			}

			logger.warn("渠道{}版本{}未配置可支付类型信息。取默认版本{}", channle, version, defaultVersion);
		}
	}

	public static void main(String[] args) {
		System.out.println(JSONObject.parse("{\"android\":{\"5.4.6\":{\"3\":[\"1\",\"2\"],\"2\":[\"1\",\"2\"],\"1\":[\"1\",\"2\"],\"7\":[\"23\",\"24\"],\"4\":[\"1\",\"2\"]}},\"h5\":{\"5.4.6\":{\"3\":[\"23\"],\"2\":[\"23\"],\"1\":[\"23\"],\"7\":[\"23\"],\"4\":[\"23\"]}},\"wx\":{\"5.4.6\":{\"3\":[\"22\"],\"2\":[\"22\"],\"1\":[\"22\"],\"7\":[\"22\"],\"4\":[\"22\"]}},\"iOS\":{\"5.4.6\":{\"3\":[\"1\",\"2\"],\"2\":[\"1\",\"2\"],\"1\":[\"1\",\"2\"],\"7\":[\"23\",\"24\"],\"4\":[\"1\",\"2\"]}}}"));
	}

	@Override
	public List<PayTypeConfig> queryOrderPayType(boolean openStoreOrder, ReqHeaderVo reqHeader, ResponseUser payUser) {
		if (openStoreOrder) {
			//			if (!reqHeader.isWX()) {
			//				logger.error("开店单只能微信渠道支付：{}-{}", reqHeader.getPhoneType(), reqHeader.getAppSystemVersion());
			//				return new ArrayList<>();
			//				//				throw new PlatformException(ErrorEnum.C21201, "开店单不支持代付");
			//			}
			String appSystemVersion = reqHeader.getAppSystemVersion();
			reqHeader.setAppSystemVersion("0.0.0");
			List<PayTypeConfig> payType = queryOrderPayType(reqHeader, payUser);
			reqHeader.setAppSystemVersion(appSystemVersion);
			return payType;
		}
		return queryOrderPayType(reqHeader, payUser);
	}

	@Override
	public List<PayTypeConfig> queryOrderPayType(ReqHeaderVo reqHeader, ResponseUser payUser) {
		//		long currentTimeMillis = System.currentTimeMillis();

		if (StringUtils.isAnyEmpty(reqHeader.getPhoneType(), reqHeader.getAppSystemVersion())) {
			throw new PlatformException("缺少头信息");
		}
		Integer roleId = payUser.getRoleId();
		//当前可用支付类型
		List<PayTypeConfig> _return_pay_type_list = new ArrayList<PayTypeConfig>();
		Map<String, String> payCfgInfo = getPayCfgInfo(reqHeader.getPhoneType(), reqHeader.getAppSystemVersion());
		if (MapUtils.isNotEmpty(payCfgInfo)) {
			Map<String, PayTypeConfig> payTypeConfig = payTypeConfigService.getPayTypeConfig();
			if (MapUtils.isNotEmpty(payTypeConfig)) {
				for (String key : payCfgInfo.keySet()) {
					String[] split = StringUtils.split(payCfgInfo.get(key), ",");
					if (ArrayUtils.contains(split, roleId.toString())) {
						_return_pay_type_list.add(payTypeConfig.get(key));
					}
				}
			}
		}
		//		logger.error("获取支付方式耗时：{}", System.currentTimeMillis() - currentTimeMillis);
		return _return_pay_type_list;

	}

	@Override
	public List<PayTypeConfig> queryOrderPayType(String phoneType, boolean isTearcher) {
		//当前可用支付类型
		List<PayTypeConfig> _return_pay_type_list = new ArrayList<PayTypeConfig>();
		//查询当前可用支付类型
		List<PayTypeConfig> check_pay_type_list = orderDao.selectPayTypeConfigByStatus(StatusEnum.S1.getCode());
		for (PayTypeConfig payTypeConfig : check_pay_type_list) {
			if (StringUtils.equalsIgnoreCase(phoneType, "wx")) {
				if (PayTypeEnum.T22.getCode().intValue() == payTypeConfig.getPayType()) {
					_return_pay_type_list.add(payTypeConfig);
				}
			} else if (StringUtils.equalsIgnoreCase(phoneType, "h5")) {
				if (PayTypeEnum.T23.getCode().intValue() == payTypeConfig.getPayType()) {
					_return_pay_type_list.add(payTypeConfig);
				}
			} else if (StringUtils.equalsAnyIgnoreCase(phoneType, "android", "iOS")) {
				switch (payTypeConfig.getPayType()) {
					case 21:
						if (isTearcher)
							break;
					case 23:
					case 24:
						_return_pay_type_list.add(payTypeConfig);
						break;

					default:
						break;
				}
			}
		}
		return _return_pay_type_list;
	}

	@Override
	public OrderObject selectOrderObjectByOrderSn(String orderSn) {
		return orderObjectMapper.selectByOrderSn(orderSn);
	}

	@Override
	public boolean isOpenStoreOrder(String paySn) {

		OrderObject _order = orderObjectMapper.selectOrderObjectByPaySn(paySn);

		if (_order == null) {
			return Boolean.FALSE;
		}

		if (_order.getOpenStore() == 1) {
			return Boolean.TRUE;
		} else {
			return Boolean.FALSE;
		}

	}
}